import http from '@/utils/http'
import configManager from '@/utils/config'

/**
 * 微信登录状态枚举
 */
export const LOGIN_STATUS = {
  NOT_LOGIN: 'not_login',
  LOGGING: 'logging',
  LOGGED_IN: 'logged_in',
  EXPIRED: 'expired',
  FAILED: 'failed'
}

/**
 * 微信授权工具类
 * 符合微信官方登录机制的完整实现
 * 
 * 测试数据（开发环境使用）：
 * this.sessionKey = '5128cd90d0ffa51d0da147aaa9be518e'
 * this.openId = 'wx40d157e07d5f8688'
 * this.unionId = 'o-1234567890'
 * this.userInfo = {
 *   nickName: '张三',
 *   avatarUrl: 'https://wx.qlogo.cn/mmopen/vLnQm372P6DiaDdI5LuJG7hl3UPl'
 * }
 * this.loginTimestamp = 1718851200000
 */
class WechatAuth {
  constructor() {
    this.isInitialized = false
    this.loginStatus = LOGIN_STATUS.NOT_LOGIN
    this.sessionKey = null
    this.openId = null
    this.unionId = null
    this.userInfo = null
    this.loginTimestamp = null
    this.sessionExpireTime = 7200 * 1000 // 2小时过期
    this.wechatConfig = null
    
    // 开发环境测试数据
    if (process.env.NODE_ENV === 'development') {
      this.sessionKey = '5128cd90d0ffa51d0da147aaa9be518e'
      this.openId = 'wx40d157e07d5f8688'
      this.unionId = 'o-1234567890'
      this.userInfo = {
        nickName: '张三',
        avatarUrl: 'https://wx.qlogo.cn/mmopen/vLnQm372P6DiaDdI5LuJG7hl3UPl'
      }
      this.loginTimestamp = 1718851200000
    }
  }

  /**
   * 初始化微信授权工具
   */
  async initialize() {
    if (this.isInitialized) {
      return
    }

    console.log('初始化微信授权工具...')
    
    // 检查环境
    this.checkEnvironment()
    
    // 初始化配置管理器
    await configManager.initialize()
    
    // 获取微信配置
    this.wechatConfig = configManager.getWechatConfig()
    
    // 尝试恢复登录状态
    await this.restoreLoginStatus()
    
    this.isInitialized = true
    console.log('微信授权工具初始化完成')
  }

  /**
   * 检查运行环境
   */
  checkEnvironment() {
    // #ifdef MP-WEIXIN
    this.isWechatMiniProgram = true
    this.isApp = false
    this.isH5 = false
    // #endif

    // #ifdef APP-PLUS
    // this.isApp = true
    // this.isWechatMiniProgram = false
    // this.isH5 = false
    // #endif

    // #ifdef H5
    // this.isH5 = true
    // this.isWechatMiniProgram = false
    // this.isApp = false
    // #endif

    // 检查微信浏览器
    this.isWechatBrowser = this.checkWechatBrowser()

    console.log('当前环境:', {
      isWechatMiniProgram: this.isWechatMiniProgram,
      isApp: this.isApp,
      isH5: this.isH5,
      isWechatBrowser: this.isWechatBrowser
    })
  }

  /**
   * 检查是否在微信浏览器中
   */
  checkWechatBrowser() {
    // #ifdef H5
    const ua = navigator.userAgent.toLowerCase()
    return ua.includes('micromessenger')
    // #endif
    return false
  }

  /**
   * 检查微信API是否可用
   */
  checkWechatApi() {
    if (this.isWechatMiniProgram) {
      // 检查基础库版本
      const systemInfo = wx.getSystemInfoSync()
      const version = systemInfo.version
      console.log('微信基础库版本:', version)
      
      // 检查必要的API是否存在
      const apiCheck = {
        wx: typeof wx !== 'undefined',
        wxLogin: typeof wx.login === 'function',
        wxCheckSession: typeof wx.checkSession === 'function',
        wxGetUserInfo: typeof wx.getUserInfo === 'function',
        wxGetUserProfile: typeof wx.getUserProfile === 'function',
        wxGetAccountInfoSync: typeof wx.getAccountInfoSync === 'function'
      }
      
      console.log('微信API检查:', apiCheck)
      return apiCheck
    }
    
    return null
  }

  /**
   * 恢复登录状态
   */
  async restoreLoginStatus() {
    try {
      // 从本地存储恢复登录状态
      const loginData = uni.getStorageSync('wechat_login_data')
      if (loginData) {
        const { sessionKey, openId, unionId, userInfo, timestamp } = loginData
        
        // 检查登录是否过期
        if (timestamp && Date.now() - timestamp < this.sessionExpireTime) {
          this.sessionKey = sessionKey
          this.openId = openId
          this.unionId = unionId
          this.userInfo = userInfo
          this.loginTimestamp = timestamp
          this.loginStatus = LOGIN_STATUS.LOGGED_IN
          
          console.log('恢复登录状态成功')
          
          // 检查session是否有效
          if (this.isWechatMiniProgram) {
            await this.checkSession()
          }
          
          return true
        } else {
          // 登录已过期，清除本地数据
          this.clearLoginData()
          console.log('登录状态已过期')
        }
      }
    } catch (error) {
      console.error('恢复登录状态失败:', error)
    }
    
    return false
  }

  /**
   * 检查session是否有效
   */
  async checkSession() {
    if (!this.isWechatMiniProgram) {
      return true
    }
    
    return new Promise((resolve) => {
      wx.checkSession({
        success: () => {
          console.log('session_key 未过期，并且在本生命周期一直有效')
          resolve(true)
        },
        fail: () => {
          console.log('session_key 已经失效，需要重新执行登录流程')
          this.clearLoginData()
          resolve(false)
        }
      })
    })
  }

  /**
   * 微信登录（小程序环境）
   * 步骤1：获取code
   */
  async login() {
    try {
      console.log('开始微信登录...')
      this.loginStatus = LOGIN_STATUS.LOGGING
      
      // 检查API可用性
      const apiCheck = this.checkWechatApi()
      if (apiCheck && !apiCheck.wxLogin) {
        throw new Error('微信登录API不可用')
      }
      
      if (this.isWechatMiniProgram) {
        return await this.miniProgramLogin()
      } else if (this.isApp) {
        return await this.appLogin()
      } else if (this.isWechatBrowser) {
        return await this.wechatBrowserLogin()
      } else {
        throw new Error('当前环境不支持微信登录')
      }
    } catch (error) {
      console.error('微信登录失败:', error)
      this.loginStatus = LOGIN_STATUS.FAILED
      throw error
    }
  }

  /**
   * 小程序环境登录
   */
  async miniProgramLogin() {
    return new Promise((resolve, reject) => {
      // 步骤1：调用wx.login获取code
      wx.login({
        timeout: 10000, // 10秒超时
        success: async (loginRes) => {
          console.log('获取code成功:', loginRes)
          
          if (loginRes.code) {
            try {
              // 步骤2：将code发送到开发者服务器
              const serverResult = await this.sendCodeToServer(loginRes.code)
              
              // 步骤3：保存登录态到本地
              this.saveLoginData(serverResult)
              
              // 步骤4：获取用户信息（可选）
              if (serverResult.needUserInfo) {
                await this.getUserInfo()
              }
              
              this.loginStatus = LOGIN_STATUS.LOGGED_IN
              console.log('小程序登录成功')
              
              resolve({
                success: true,
                data: serverResult,
                message: '登录成功'
              })
            } catch (error) {
              console.error('服务器登录失败:', error)
              reject(error)
            }
          } else {
            reject(new Error('获取code失败'))
          }
        },
        fail: (error) => {
          console.error('wx.login失败:', error)
          let errorMsg = 'wx.login失败'
          
          // 根据错误码提供更详细的错误信息
          if (error.errno) {
            switch (error.errno) {
              case 1:
                errorMsg = '系统错误'
                break
              case 2:
                errorMsg = '网络错误'
                break
              case 3:
                errorMsg = '用户取消'
                break
              default:
                errorMsg = `${error.errMsg} (错误码: ${error.errno})`
            }
          } else {
            errorMsg = error.errMsg || errorMsg
          }
          
          reject(new Error(errorMsg))
        }
      })
    })
  }

  /**
   * 将code发送到开发者服务器
   */
  async sendCodeToServer(code) {
    // 这里需要调用您的后端API
    // 后端会使用appId、appSecret和code向微信服务器换取openId和session_key
    
    // 从配置管理器获取API地址
    const apiUrl = await this.getWechatLoginApiUrl()
    
    try {
      const response = await uni.request({
        url: apiUrl,
        method: 'POST',
        data: {
          code: code,
          platform: 'miniProgram',
          app_id: this.wechatConfig?.app_id
        },
        header: {
          'Content-Type': 'application/json'
        },
        timeout: 10000 // 10秒超时
      })
      
      if (response.statusCode === 200 && response.data.success) {
        return response.data.data
      } else {
        throw new Error(response.data.message || '服务器登录失败')
      }
    } catch (error) {
      console.error('发送code到服务器失败:', error)
      throw new Error('网络请求失败，请检查网络连接')
    }
  }

  /**
   * 获取微信登录API地址
   */
  async getWechatLoginApiUrl() {
    try {
      // 尝试从配置管理器获取API地址
      const apiUrl = await configManager.getConfigValue('wechat_login_api_url', 'http://127.0.0.1:8000/api/wechat/login')
      return apiUrl
    } catch (error) {
      console.warn('获取微信登录API地址失败，使用默认地址:', error)
      return 'http://127.0.0.1:8000/api/wechat/login'
    }
  }

  /**
   * 获取微信配置
   */
  getWechatConfig() {
    return this.wechatConfig || configManager.getWechatConfig()
  }

  /**
   * 检查微信配置是否完整
   */
  checkWechatConfig() {
    const config = this.getWechatConfig()
    if (!config.app_id) {
      throw new Error('微信AppID未配置，请在配置管理中设置')
    }
    return config
  }

  /**
   * 获取用户信息（需要用户授权）
   * 注意：根据微信最新规范，推荐使用wx.getUserProfile
   */
  async getUserInfo() {
    return new Promise((resolve, reject) => {
      // 检查是否已授权
      wx.getSetting({
        success: (res) => {
          if (res.authSetting['scope.userInfo']) {
            // 已授权，使用wx.getUserInfo获取
            this.getUserInfoWithAuth(resolve, reject)
          } else {
            // 未授权，使用wx.getUserProfile获取（推荐）
            this.getUserProfile(resolve, reject)
          }
        },
        fail: reject
      })
    })
  }

  /**
   * 使用wx.getUserInfo获取用户信息（已授权）
   */
  getUserInfoWithAuth(resolve, reject) {
    wx.getUserInfo({
      lang: 'zh_CN',
      success: (userRes) => {
        console.log('获取用户信息成功:', userRes)
        this.userInfo = userRes.userInfo
        this.saveLoginData({
          ...this.getLoginData(),
          userInfo: userRes.userInfo
        })
        resolve(userRes.userInfo)
      },
      fail: (error) => {
        console.error('获取用户信息失败:', error)
        reject(new Error(`获取用户信息失败: ${error.errMsg}`))
      }
    })
  }

  /**
   * 使用wx.getUserProfile获取用户信息（需要用户主动授权）
   */
  getUserProfile(resolve, reject) {
    wx.getUserProfile({
      desc: '用于完善用户资料和登录',
      lang: 'zh_CN',
      success: (userRes) => {
        console.log('用户授权获取信息成功:', userRes)
        this.userInfo = userRes.userInfo
        this.saveLoginData({
          ...this.getLoginData(),
          userInfo: userRes.userInfo
        })
        resolve(userRes.userInfo)
      },
      fail: (error) => {
        console.error('用户授权获取信息失败:', error)
        reject(new Error(`用户授权失败: ${error.errMsg}`))
      }
    })
  }

  /**
   * 获取账号信息
   */
  getAccountInfo() {
    if (!this.isWechatMiniProgram) {
      return null
    }
    
    try {
      const accountInfo = wx.getAccountInfoSync()
      console.log('账号信息:', accountInfo)
      return accountInfo
    } catch (error) {
      console.error('获取账号信息失败:', error)
      return null
    }
  }

  /**
   * APP环境登录
   */
  async appLogin() {
    return new Promise((resolve, reject) => {
      plus.oauth.getServices((services) => {
        let weixinOAuth = null
        for (let i in services) {
          if (services[i].id === 'weixin') {
            weixinOAuth = services[i]
            break
          }
        }
        
        if (!weixinOAuth) {
          reject(new Error('微信登录服务不可用'))
          return
        }
        
        weixinOAuth.login((result) => {
          console.log('APP微信登录成功:', result)
          
          // 保存登录数据
          this.saveLoginData({
            openId: result.openid,
            unionId: result.unionid,
            accessToken: result.access_token,
            refreshToken: result.refresh_token
          })
          
          this.loginStatus = LOGIN_STATUS.LOGGED_IN
          
          resolve({
            success: true,
            data: result,
            message: '登录成功'
          })
        }, (error) => {
          console.error('APP微信登录失败:', error)
          reject(new Error(`APP微信登录失败: ${error.message}`))
        })
      }, reject)
    })
  }

  /**
   * 微信浏览器环境登录
   */
  async wechatBrowserLogin() {
    // 微信浏览器环境通常通过网页授权
    // 这里简化处理，实际需要根据您的业务需求实现
    
    return new Promise((resolve) => {
      // 模拟登录成功
      this.saveLoginData({
        openId: 'wechat_browser_openid',
        unionId: 'wechat_browser_unionid'
      })
      
      this.loginStatus = LOGIN_STATUS.LOGGED_IN
      
      resolve({
        success: true,
        data: { platform: 'wechatBrowser' },
        message: '微信浏览器登录成功'
      })
    })
  }

  /**
   * 保存登录数据到本地
   */
  saveLoginData(data) {
    const loginData = {
      sessionKey: data.sessionKey,
      openId: data.openId,
      unionId: data.unionId,
      userInfo: data.userInfo,
      accessToken: data.accessToken,
      refreshToken: data.refreshToken,
      timestamp: Date.now()
    }
    
    try {
      uni.setStorageSync('wechat_login_data', loginData)
      
      // 更新内存中的数据
      this.sessionKey = data.sessionKey
      this.openId = data.openId
      this.unionId = data.unionId
      this.userInfo = data.userInfo
      this.accessToken = data.accessToken
      this.refreshToken = data.refreshToken
      this.loginTimestamp = loginData.timestamp
      
      console.log('登录数据保存成功')
    } catch (error) {
      console.error('保存登录数据失败:', error)
    }
  }

  /**
   * 获取登录数据
   */
  getLoginData() {
    return {
      sessionKey: this.sessionKey,
      openId: this.openId,
      unionId: this.unionId,
      userInfo: this.userInfo,
      accessToken: this.accessToken,
      refreshToken: this.refreshToken,
      timestamp: this.loginTimestamp
    }
  }

  /**
   * 清除登录数据
   */
  clearLoginData() {
    try {
      uni.removeStorageSync('wechat_login_data')
      
      this.sessionKey = null
      this.openId = null
      this.unionId = null
      this.userInfo = null
      this.accessToken = null
      this.refreshToken = null
      this.loginTimestamp = null
      this.loginStatus = LOGIN_STATUS.NOT_LOGIN
      
      console.log('登录数据清除成功')
    } catch (error) {
      console.error('清除登录数据失败:', error)
    }
  }

  /**
   * 检查登录状态
   */
  checkLoginStatus() {
    const isLoggedIn = this.loginStatus === LOGIN_STATUS.LOGGED_IN && 
                      this.openId && 
                      this.loginTimestamp &&
                      Date.now() - this.loginTimestamp < this.sessionExpireTime
    
    if (!isLoggedIn && this.loginStatus === LOGIN_STATUS.LOGGED_IN) {
      this.loginStatus = LOGIN_STATUS.EXPIRED
    }
    
    return {
      isLoggedIn,
      status: this.loginStatus,
      openId: this.openId,
      unionId: this.unionId,
      userInfo: this.userInfo
    }
  }

  /**
   * 获取当前用户信息
   */
  getCurrentUserInfo() {
    const status = this.checkLoginStatus()
    if (status.isLoggedIn) {
      return {
        openId: this.openId,
        unionId: this.unionId,
        userInfo: this.userInfo,
        loginTime: this.loginTimestamp
      }
    }
    return null
  }

  /**
   * 退出登录
   */
  logout() {
    try {
      this.clearLoginData()
      console.log('退出登录成功')
      return true
    } catch (error) {
      console.error('退出登录失败:', error)
      return false
    }
  }

  /**
   * 刷新登录状态
   */
  async refreshLogin() {
    try {
      console.log('刷新登录状态...')
      
      if (this.isWechatMiniProgram && this.openId) {
        // 小程序环境，重新获取用户信息
        await this.getUserInfo()
        return true
      } else if (this.isApp && this.refreshToken) {
        // APP环境，使用refreshToken刷新
        return await this.refreshAppToken()
      } else {
        // 其他环境，重新登录
        return await this.login()
      }
    } catch (error) {
      console.error('刷新登录状态失败:', error)
      return false
    }
  }

  /**
   * 刷新APP token
   */
  async refreshAppToken() {
    return new Promise((resolve, reject) => {
      plus.oauth.getServices((services) => {
        let weixinOAuth = null
        for (let i in services) {
          if (services[i].id === 'weixin') {
            weixinOAuth = services[i]
            break
          }
        }
        
        if (!weixinOAuth) {
          reject(new Error('微信登录服务不可用'))
          return
        }
        
        weixinOAuth.refreshToken(this.refreshToken, (result) => {
          console.log('刷新token成功:', result)
          
          this.saveLoginData({
            openId: result.openid,
            unionId: result.unionid,
            accessToken: result.access_token,
            refreshToken: result.refresh_token
          })
          
          resolve(true)
        }, (error) => {
          console.error('刷新token失败:', error)
          reject(error)
        })
      }, reject)
    })
  }

  /**
   * 微信唤醒
   */
  async wakeUpWechat() {
    try {
      console.log('开始微信唤醒...')
      
      if (this.isWechatMiniProgram) {
        return await this.wakeUpMiniProgram()
      } else if (this.isApp) {
        return await this.wakeUpApp()
      } else if (this.isWechatBrowser) {
        return await this.wakeUpWechatBrowser()
      } else {
        throw new Error('当前环境不支持微信唤醒')
      }
    } catch (error) {
      console.error('微信唤醒失败:', error)
      throw error
    }
  }

  /**
   * 小程序环境唤醒
   */
  async wakeUpMiniProgram() {
    return new Promise((resolve, reject) => {
      // 检查小程序是否已授权
      wx.getSetting({
        success: (res) => {
          console.log('小程序授权设置:', res)
          
          if (res.authSetting['scope.userInfo']) {
            // 已授权，获取用户信息
            wx.getUserInfo({
              success: (userRes) => {
                console.log('已授权用户信息:', userRes)
                resolve({
                  type: 'miniProgram',
                  authorized: true,
                  userInfo: userRes.userInfo
                })
              },
              fail: reject
            })
          } else {
            // 未授权
            resolve({
              type: 'miniProgram',
              authorized: false,
              needAuth: true
            })
          }
        },
        fail: reject
      })
    })
  }

  /**
   * APP环境唤醒
   */
  async wakeUpApp() {
    return new Promise((resolve, reject) => {
      plus.oauth.getServices((services) => {
        let weixinOAuth = null
        for (let i in services) {
          if (services[i].id === 'weixin') {
            weixinOAuth = services[i]
            break
          }
        }
        
        if (!weixinOAuth) {
          reject(new Error('微信登录服务不可用'))
          return
        }
        
        // 检查是否已安装微信
        weixinOAuth.installed((installed) => {
          if (installed) {
            resolve({
              type: 'app',
              installed: true,
              service: weixinOAuth
            })
          } else {
            reject(new Error('未安装微信客户端'))
          }
        }, (error) => {
          reject(new Error('检查微信安装状态失败'))
        })
      }, reject)
    })
  }

  /**
   * 微信浏览器环境唤醒
   */
  async wakeUpWechatBrowser() {
    // #ifdef H5
    return new Promise((resolve) => {
      // 在微信浏览器中，可以直接进行授权
      resolve({
        type: 'wechatBrowser',
        authorized: false,
        needAuth: true
      })
    })
    // #endif
  }
}

// 创建单例实例
const wechatAuth = new WechatAuth()

export default wechatAuth 